package com.sugon.modules.mold.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.ModuleStatusChangeRecordDao;
import com.sugon.dao.ModuleTypeDao;
import com.sugon.entity.*;
import com.sugon.modules.mold.consts.MoldState;
import com.sugon.modules.mold.consts.MoldStatusChangeAction;
import com.sugon.modules.mold.model.vo.MoldHealthyStatusVO;
import com.sugon.modules.mold.service.IMoldArchivesManager;
import com.sugon.service.*;
import com.sugon.utils.Constant;
import com.sugon.utils.PageUtils;
import com.sugon.utils.Query;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ： YuXD
 * @description： 模具档案Manager实现类
 * @date ： 2021-03-19 下午 2:22
 * @version: 1.0
 */
@Slf4j
@Service
public class MoldArchivesManagerImpl implements IMoldArchivesManager {

    @Resource
    private ModuleTypeDao moduleTypeDao;
    @Resource
    private ModuleTypeService moldTypeService;
    @Resource
    private ModuleArchivesService moldService;
    @Resource
    private ModuleStatusChangeRecordService moduleStatusChangeRecordService;
    @Resource
    private ModuleStatusChangeRecordDao moduleStatusChangeRecordDao;
    @Resource
    private ModuleTypePositionService moldTypePositionService;
    @Resource
    private ModulPositionCorrelationService moldPositionCorrelationService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean newlyAdd(ModuleArchivesEntity mold) {
        int saveNum = moldService.save(mold);
        Assert.isTrue(saveNum > 0);
        // 获取当前模具分类下是否已有关联位置。如果有则将已关联的位置同模具关联
        String moldType = mold.getModuleType();
        Assert.isTrue(StrUtil.isNotEmpty(moldType), "模具类型ID不能为空！");
        List<MoldTypePositionEntity> moldTypePositionList = moldTypePositionService.queryList(moldType);
        if (CollectionUtil.isNotEmpty(moldTypePositionList)) {
            ModulPositionCorrelationEntity moldPos;
            for (MoldTypePositionEntity moldTypePosition : moldTypePositionList) {
                moldPos = new ModulPositionCorrelationEntity();
                moldPos.setMoldId(mold.getId());
                moldPos.setMoldTypePosId(moldTypePosition.getId());
                moldPositionCorrelationService.save(moldPos);
            }
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean update(ModuleArchivesEntity mold) {
        ModuleArchivesEntity existedMold = moldService.queryObject(mold.getId());
        Assert.notNull(existedMold);
        // 更新模具信息
        int saveNum = moldService.update(mold);
        Assert.isTrue(saveNum > 0);

        // 获取当前模具分类下是否已有关联位置。如果有则将已关联的位置同模具关联
        String moldType = mold.getModuleType();
        Assert.isTrue(StrUtil.isNotEmpty(moldType), "模具类型ID不能为空！");
        /*
            如果模具分类更换，则需要更新模具关联位置
         */
        if (!moldType.equals(existedMold.getModuleType())) {
            // 删除现有位置关联
            moldPositionCorrelationService.clearAll(mold.getId());
            // 保存新的位置关联
            List<MoldTypePositionEntity> moldTypePositionList = moldTypePositionService.queryList(moldType);
            if (CollectionUtil.isNotEmpty(moldTypePositionList)) {
                ModulPositionCorrelationEntity moldPos;
                for (MoldTypePositionEntity moldTypePosition : moldTypePositionList) {
                    moldPos = new ModulPositionCorrelationEntity();
                    moldPos.setMoldId(mold.getId());
                    moldPos.setMoldTypePosId(moldTypePosition.getId());
                    moldPositionCorrelationService.save(moldPos);
                }
            }
        }
        return true;
    }

    @Override
    public PageUtils queryList(Map<String, Object> params) {
        Query query = new Query(params);
        List<ModuleArchivesEntity> moduleArchivesList = moldService.queryList(query);
        int total = moldService.queryTotal(query);
        return new PageUtils(moduleArchivesList, total, query.getLimit(), query.getPage());
    }

    @Override
    public List<MoldHealthyStatusVO> loadWorkshopMoldHealthyStatusData(String foundryWorkshopId, String productModel, Integer moldStatus) {
        // 获取模具类别+模具树
        List<MoldHealthyStatusVO> moldStatusDataList = moduleTypeDao.loadMoldTypeTree(foundryWorkshopId, productModel, moldStatus);
        // 获取包含统计占比的模具分类
        List<ModuleTypeEntity> moldTypeList = moldTypeService.loadComplexMoldType(foundryWorkshopId, productModel, CollectionUtil.newArrayList(MoldState.MUJUBAOFEI.getState(), MoldState.XIANGKUAIBAOFEI.getState()));
        Map<String, List<ModuleTypeEntity>> moldTypeMap = moldTypeList.stream().collect(Collectors.groupingBy(ModuleTypeEntity::getId));
        /*
            由于有些铸造车间目前并没有模具关联
            所以需要去除没有模具的模具分类，包括一级和二级分类
         */
        for (MoldHealthyStatusVO firstMoldType : moldStatusDataList) {
            List<MoldHealthyStatusVO> secondMoldTypeList = firstMoldType.getChildren();
            if (CollectionUtil.isEmpty(secondMoldTypeList)) {
                continue;
            }
            // 先处理下二级分类的总数+可用数
            secondMoldTypeList = secondMoldTypeList.stream().filter(secondMoldType -> CollectionUtil.isNotEmpty(secondMoldType.getChildren())).collect(Collectors.toList());
            for (MoldHealthyStatusVO secondMoldType : secondMoldTypeList) {
                List<ModuleTypeEntity> matchedList = moldTypeMap.get(secondMoldType.getId());
                if (CollectionUtil.isNotEmpty(matchedList)) {
                    secondMoldType.setTotalNum(matchedList.get(0).getTotalNum());
                    secondMoldType.setAvailableNum(matchedList.get(0).getAvailableNum());
                }
            }
            firstMoldType.setChildren(secondMoldTypeList);
            // 其次处理一级分类的总数+ 可用数
            List<ModuleTypeEntity> matchedList = moldTypeMap.get(firstMoldType.getId());
            if (CollectionUtil.isNotEmpty(matchedList)) {
                firstMoldType.setTotalNum(matchedList.get(0).getTotalNum());
                firstMoldType.setAvailableNum(matchedList.get(0).getAvailableNum());
            }
        }
        moldStatusDataList = moldStatusDataList.stream().filter(firstMoldType -> CollectionUtil.isNotEmpty(firstMoldType.getChildren())).collect(Collectors.toList());
        return moldStatusDataList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized boolean changeStatusByMoldId(String moldId, String moldNo, MoldStatusChangeAction moldStatusChangeAction) {
        boolean changeFlag = false;
        ModuleArchivesEntity moduleArchives = null;
        if (StrUtil.isNotEmpty(moldId)) {
            // 获取模具档案信息
            moduleArchives = moldService.queryObject(moldId);
        } else if (StrUtil.isNotEmpty(moldNo)) {
            // 获取模具档案信息
            moduleArchives = moldService.queryObjectByNo(moldId = moldNo);
        }
        // 如果模具不存在，不做任何处理
        if (moduleArchives != null) {
            changeFlag = changeMoldStatus(moduleArchives, moldStatusChangeAction);
        }
        return changeFlag;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized boolean recoverStatusByMoldId(String moldId) {
        // 获取模具档案信息
        ModuleArchivesEntity moduleArchives = moldService.queryObject(moldId);
        if (moduleArchives == null) {
            log.error("模具[{}]不存在，请确认！", moldId);
            return true;
        }
        // 获取模具状态变更记录
        Integer moldState = MoldState.LIANGCHAN.getState();
        ModuleStatusChangeRecordEntity changeRecord = moduleStatusChangeRecordDao.getLastestStatusChangeRecordByMoldId(moldId);
        if (changeRecord != null) {
            moldState = changeRecord.getPreviousStatus();
            changeRecord.setDelFlag(Constant.IS_DEL_INT);
            moduleStatusChangeRecordService.update(changeRecord);
        }
        // 修改模具当前状态并失效模具变更记录
        moduleArchives.setCurrentState(moldState);
        return moldService.update(moduleArchives) > 0;
    }

    @Override
    public boolean doMoldPm(String moldId) {
        ModuleArchivesEntity mold = moldService.queryObject(moldId);
        cn.hutool.core.lang.Assert.notNull(mold);
        mold.setCurrentState(MoldState.WEIHU.getState());
        /*
            获取模具最近一次维护时间
            同当前时间进行比较
            如果最近一次维护时间为空，或者晚于当前系统时间
            则设置最新的记录：最近一次维护时间、最近一次维护后累计的模次数置为0
         */
        // 当前系统时间
        DateTime current = DateUtil.date();
        // 模具档案中最近一次维护时间
        Date newlyPmDate = mold.getNewlyPmDate();
        if (newlyPmDate == null || DateUtil.compare(newlyPmDate, current) < 0) {
            mold.setNewlyAccumulateMt(0);
            mold.setNewlyPmDate(current);
        }
        return moldService.update(mold) > 0;
    }

    /**
     * 更改模具状态
     */
    private synchronized boolean changeMoldStatus(ModuleArchivesEntity moduleArchives, MoldStatusChangeAction moldStatusChangeAction) {
        boolean changeFlag = false;
        // 生成模具状态变更记录
        ModuleStatusChangeRecordEntity changeRecord = new ModuleStatusChangeRecordEntity(moduleArchives.getId(), moduleArchives.getModuleNo(), moldStatusChangeAction.name(), moduleArchives.getCurrentState(), moldStatusChangeAction.getMoldState().getState());
        // 修改模具当前状态并记录状态变更信息
        moduleArchives.setCurrentState(moldStatusChangeAction.getMoldState().getState());
        if (moldService.update(moduleArchives) > 0) {
            changeFlag = moduleStatusChangeRecordService.save(changeRecord) > 0;
        }
        return changeFlag;
    }

}
